<template>
  <div class="table-fields-container">
    <div class="fields-header">
      <GapedRow>
        <span>显示字段</span>
        <GapedRow>
          <el-tooltip content="全选" placement="top">
            <el-button type="text" size="small" @click="selectAllFields">
              <el-icon><Select /></el-icon>
            </el-button>
          </el-tooltip>
          <el-tooltip content="全部取消" placement="top">
            <el-button type="text" size="small" @click="deselectAllFields">
              <el-icon><CircleClose /></el-icon>
            </el-button>
          </el-tooltip>
          <el-tooltip content="取消" placement="top">
            <el-button type="text" size="small" @click="resetFields">
              <el-icon><Close /></el-icon>
            </el-button>
          </el-tooltip>
          <el-tooltip content="使用" placement="top">
            <el-button type="text" size="small" @click="applyFields">
              <el-icon><Check /></el-icon>
            </el-button>
          </el-tooltip>
        </GapedRow>
      </GapedRow>
    </div>
    <div class="fields-list">
      <el-scrollbar>
        <div v-for="field in sortedFields" :key="field.name" class="field-item">
          <el-checkbox
            v-model="selectedFields"
            :label="field.name"
            :disabled="field.alwaysSelected"
            @change="updateVisibleFields"
          />
          <span class="field-label">{{ field.label }}</span>
        </div>
      </el-scrollbar>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, watch, computed, onMounted } from 'vue'
import type { OptionField } from './types'
import { Close, Check, Select, CircleClose } from '@element-plus/icons-vue'
import { GapedRow } from '@/core/components'

const props = defineProps<{
  optionFields: Array<OptionField>
  modelValue: string[]
  tableName: string
}>()

const emit = defineEmits<{
  (e: 'update:modelValue', value: string[]): void
}>()

const selectedFields = ref([...props.modelValue])
const originalFields = ref([...props.modelValue])

const STORAGE_KEY = 'selectedTableFields'
const saveSelected = (fields: string[]) => {
  localStorage.setItem(
    `${STORAGE_KEY}_${props.tableName}`,
    JSON.stringify(fields)
  )
}

const loadSelected = (): string[] => {
  const saved = localStorage.getItem(`${STORAGE_KEY}_${props.tableName}`)
  if (saved) {
    return JSON.parse(saved)
  }
  return props.optionFields.map(field => field.name)
}

const initSelectedFields = () => {
  const loadedFields = loadSelected()
  if (loadedFields.length > 0) {
    selectedFields.value = loadedFields
    originalFields.value = loadedFields
    emit('update:modelValue', loadedFields)
  } else {
    const alwaysSelectedFields = props.optionFields
      .filter(field => field.alwaysSelected)
      .map(field => field.name)

    selectedFields.value = [
      ...new Set([...selectedFields.value, ...alwaysSelectedFields]),
    ]
  }
}

onMounted(() => {
  initSelectedFields()
})

const sortedFields = computed(() => {
  // 分离出alwaysSelected和非alwaysSelected的字段
  const alwaysSelected = props.optionFields.filter(f => f.alwaysSelected)
  const nonAlwaysSelected = props.optionFields.filter(f => !f.alwaysSelected)

  // 按照selectedFields的顺序排序非alwaysSelected字段
  const sortedNonAlwaysSelected = [...nonAlwaysSelected].sort((a, b) => {
    const aIndex = selectedFields.value.indexOf(a.name)
    const bIndex = selectedFields.value.indexOf(b.name)

    // 如果都在selectedFields中，按selectedFields的顺序
    if (aIndex !== -1 && bIndex !== -1) return aIndex - bIndex
    // 只有a在selectedFields中，a排前面
    if (aIndex !== -1) return -1
    // 只有b在selectedFields中，b排前面
    if (bIndex !== -1) return 1
    // 都不在selectedFields中，按字符串顺序排序
    return a.name.localeCompare(b.name)
  })

  // 合并结果，alwaysSelected字段放在最后
  return [...sortedNonAlwaysSelected, ...alwaysSelected]
})

watch(
  () => props.modelValue,
  newVal => {
    originalFields.value = [...newVal]
    selectedFields.value = [...newVal]
  }
)

watch(
  () => props.optionFields,
  () => {
    initSelectedFields()
  },
  { immediate: true }
)

const updateVisibleFields = () => {
  const alwaysSelectedFields = props.optionFields
    .filter(field => field.alwaysSelected)
    .map(field => field.name)

  selectedFields.value = [
    ...new Set([...selectedFields.value, ...alwaysSelectedFields]),
  ]
}

const selectAllFields = () => {
  selectedFields.value = props.optionFields
    .filter(field => !field.alwaysSelected)
    .map(field => field.name)
  updateVisibleFields()
}

const deselectAllFields = () => {
  selectedFields.value = props.optionFields
    .filter(field => field.alwaysSelected)
    .map(field => field.name)
}

const resetFields = () => {
  selectedFields.value = [...originalFields.value]
}

const applyFields = () => {
  originalFields.value = [...selectedFields.value]
  saveSelected(selectedFields.value)
  emit('update:modelValue', selectedFields.value)
}
</script>

<style scoped>
.table-fields-container {
  border-left: 1px solid var(--el-border-color);
  padding-left: 16px;
  height: 100%;
  display: flex;
  flex-direction: column;
}

.fields-header {
  font-weight: 600;
  margin-bottom: 12px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.fields-list {
  flex: 1;
  overflow: hidden;
}

.field-item {
  display: flex;
  align-items: center;
  margin-bottom: 8px;
}

.field-label {
  margin-left: 8px;
  font-size: 14px;
}
</style>
